package k8s

import (
	"time"
)

// EventType represents the type of resource event
type EventType string

const (
	// EventTypeStatefulSetChanged represents a StatefulSet change event
	EventTypeStatefulSetChanged EventType = "StatefulSetChanged"
	// EventTypePVCChanged represents a PersistentVolumeClaim change event
	EventTypePVCChanged EventType = "PVCChanged"
	// EventTypePVChanged represents a PersistentVolume change event
	EventTypePVChanged EventType = "PVChanged"
	// EventTypePyTorchJobChanged represents a PyTorchJob change event
	EventTypePyTorchJobChanged EventType = "PyTorchJobChanged"
)

// ResourceEvent represents a Kubernetes resource event
type ResourceEvent struct {
	Type      EventType         `json:"type"`
	Resource  string            `json:"resource"`
	Name      string            `json:"name"`
	Namespace string            `json:"namespace"`
	Status    string            `json:"status"`
	Labels    map[string]string `json:"labels"`
	Timestamp time.Time         `json:"timestamp"`
}

// EventGenerator generates events for Kubernetes resources
type EventGenerator struct {
	eventChannel chan *ResourceEvent
}

// NewEventGenerator creates a new event generator
func NewEventGenerator(bufferSize int) *EventGenerator {
	return &EventGenerator{
		eventChannel: make(chan *ResourceEvent, bufferSize),
	}
}

// GetEventChannel returns the event channel
func (eg *EventGenerator) GetEventChannel() <-chan *ResourceEvent {
	return eg.eventChannel
}

// SendEvent sends an event to the event channel
func (eg *EventGenerator) SendEvent(event *ResourceEvent) {
	select {
	case eg.eventChannel <- event:
		// Event sent successfully
	default:
		// Channel is full, drop the event
		// In a real implementation, you might want to log this
	}
}

// Close closes the event generator
func (eg *EventGenerator) Close() {
	close(eg.eventChannel)
}

// EventHandler defines the interface for handling resource events
type EventHandler interface {
	HandleEvent(event *ResourceEvent) error
}

// DefaultEventHandler is a default implementation of EventHandler
type DefaultEventHandler struct {
	handlers map[EventType]func(*ResourceEvent) error
}

// NewDefaultEventHandler creates a new default event handler
func NewDefaultEventHandler() *DefaultEventHandler {
	return &DefaultEventHandler{
		handlers: make(map[EventType]func(*ResourceEvent) error),
	}
}

// RegisterHandler registers a handler for a specific event type
func (h *DefaultEventHandler) RegisterHandler(eventType EventType, handler func(*ResourceEvent) error) {
	h.handlers[eventType] = handler
}

// HandleEvent handles a resource event
func (h *DefaultEventHandler) HandleEvent(event *ResourceEvent) error {
	if handler, exists := h.handlers[event.Type]; exists {
		return handler(event)
	}
	// Default behavior: do nothing
	return nil
}

// EventProcessor processes events from the event generator
type EventProcessor struct {
	generator *EventGenerator
	handler   EventHandler
	stopChan  chan struct{}
}

// NewEventProcessor creates a new event processor
func NewEventProcessor(generator *EventGenerator, handler EventHandler) *EventProcessor {
	return &EventProcessor{
		generator: generator,
		handler:   handler,
		stopChan:  make(chan struct{}),
	}
}

// Start starts the event processor
func (ep *EventProcessor) Start() {
	go func() {
		for {
			select {
			case event := <-ep.generator.GetEventChannel():
				if err := ep.handler.HandleEvent(event); err != nil {
					// In a real implementation, you might want to log this error
					// or send it to a monitoring system
				}
			case <-ep.stopChan:
				return
			}
		}
	}()
}

// Stop stops the event processor
func (ep *EventProcessor) Stop() {
	close(ep.stopChan)
}
